/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Model;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 *
 * @author aj48640
 */
public class Trajet 
{
    //Les différentes adresses
    private String adresseLivreur;
    private String[] adresseRestaurant;
    private String adresseClient;
    
    //Le polyline pour afficher les directions à prendre pour le livreur
    private String directionsPolyline;
    
    //Les fragments de l'URL pour aller chercher le XML de la destination
    private final String GoogleMapsDistanceURL = "http://maps.googleapis.com/maps/api/directions/xml?origin=";
    private final String GoogleMapsDistanceDestination = "&destination=";
    private final String GoogleMapsDistanceWaypoint = "&waypoints=optimize:true|";
    private final String GoogleMapsDistanceFinal = "&sensor=false";
    
    //L'URL pour avoir une image avec la map
    private final String GoogleMapsURL = "http://maps.google.com/maps/api/staticmap?size=400x400&sensor=false&path=weight:5|color:red|enc:";
    
    //Le label doit avoir une syntaxe : label:nomLabel|Adresse
    private final String GoogleMapsMarker = "&markers=color:blue|label:";
    
    /***
     * Constructeur par défaut
     * @param adresseLivreur adresse du livreur
     * @param adresseRestaurant adresse du restaurant
     * @param adresseClient adresse du client
     */
    public Trajet(String adresseLivreur,String[] adresseRestaurant,String adresseClient)
    {
        this.adresseLivreur = adresseLivreur;
        this.adresseRestaurant = adresseRestaurant;
        this.adresseClient = adresseClient;
    }
    
    /**
     * Permet de donner l'URL de l'image de la map
     * La fonction CalculateDirections doit avoir été appelé avant.
     * @return 
     */
    public String GetURLMap ()
    {
        return GoogleMapsURL + this.directionsPolyline +
                GoogleMapsMarker + GetMarker("L",this.adresseLivreur) +
                GoogleMapsMarker + GetMarker("R", this.adresseRestaurant) +
                GoogleMapsMarker + GetMarker("C", this.adresseClient);
    }
    
    private String GetMarker (String label,String[] adress )
    {
        String tmp = "";
        
        for (String i : adress)
            tmp += label+"|"+i.replaceAll(" ", "%20");
        return tmp;
    }
    
    /**
     * Calcule les directions pour les adresse
     * @return Status du calcul
     */
    public boolean CalculateDirections()
    {
        try
        {
            URL googleMapsDistance = new URL(getGoogleMapsDistanceURL());
            URLConnection googleMapsDistanceConnection = googleMapsDistance.openConnection();
            
            ParseXMLDistance(googleMapsDistanceConnection.getInputStream()); 
            return true;
        }
        catch (Exception e)
        {
            return false;
        } 
    }
    
    /**
     * Méthode Helper pour avoir une string pour un marker sur la map
     * @param label
     * @param adress
     * @return 
     */
    private String GetMarker(String label,String adress)
    {
        return label+"|"+adress.replaceAll(" ", "%20");
    }
    
    /**
     * Contruit l'URL pour calculer la distance avec google Maps
     * @return 
     */
    private String getGoogleMapsDistanceURL()
    {
        String tmp = "";
        for (String i : this.adresseRestaurant)
            tmp+=i.replaceAll(" ", "%20")+"|";
        
        tmp = tmp.substring(0,tmp.length()-1);
        
        return GoogleMapsDistanceURL + this.adresseLivreur.replaceAll(" ", "%20") +
                GoogleMapsDistanceDestination + this.adresseClient.replaceAll(" ", "%20") +
                GoogleMapsDistanceWaypoint + tmp +
                GoogleMapsDistanceFinal;
    }
    
    
    
    /**
     * Cherche le Polyline de direction dans l'URL
     * @param xml
     * @throws Exception 
     */
    private void ParseXMLDistance(InputStream xml) throws Exception
    {
        try  
        {
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(xml);
            
            doc.getDocumentElement().normalize();
            Element e = (Element)doc.getElementsByTagName("overview_polyline").item(0);
            
            //Les données des directions à prendre pour arriver à destination
            CharacterData cd = (CharacterData)e.getElementsByTagName("points").item(0).getFirstChild();
            
            this.directionsPolyline = cd.getData();
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            throw e;
        }
    }
    
    
}
